<template>
  <div style="height: 100%; width: 100%">
    <WujieVue
      v-if="url"
      :alive="keepAlive"
      width="100%"
      height="100%"
      :name="appName"
      :url="url"
      :sync="true"
      :props="{
        appName: appName,
        microData,
        permissions,
        jump,
        addRouteAndJump
      }"
      :activated="activated"
      :after-mount="afterMount"
      :plugins="plugins"
    />
  </div>
</template>

<script lang="ts" setup>
import WujieVue from 'wujie-vue3';
import { useRouter, useRoute } from 'vue-router';

import { useUserStore } from '@/store/user';
import { useMicroStore } from '@/store/micro';
import { openNewPlatformTabCommon } from '../microutils/MicroTools';
import { getToken } from '@/utils/common-util';
import { plugins } from '@/utils/micro-plugins';

const { bus } = WujieVue;
const { proxy } = getCurrentInstance();
const route = useRoute();
const router = useRouter();
const userStore = useUserStore();
const microStore = useMicroStore();

const props = defineProps({
  /** 子应用路由信息 */
  microParams: { type: Object, required: false, default: undefined }
});

const appName = ref('app1');
const url = ref('');
const keepAlive = ref(true);

const microData = ref({});
const routerParams = ref({});
const permissions = ref();
// watch(()=>route,function(){
//   url.value = null;
// },{
//   deep: true
// })
// computed: {
//   ...mapGetters({ vuexTheme: 'cfg' }),
//   skin() {
//     return this.vuexTheme && this.vuexTheme.skin;
//   }
// },
// watch: {
// $route: {
//   handler() {
//     url.value = null;
//   },
//   // 深度观察监听
//   deep: true
// }
// skin: {
//   // 皮肤切换监听事件
//   handler(val, oldval) {
//     if (val !== oldval) {
//       bus.$emit(appName.value, {
//         action: 'skin-change',
//         data: this.vuexTheme
//       });
//     }
//   },
//   // 深度观察监听
//   deep: true
// }
// },
onActivated(() => {
  reInit();
});
onDeactivated(() => {
  url.value = null;
});
onMounted(() => {
  init();
});

onBeforeUnmount(() => {
  keepAlive.value = false;
  handleRouteRemove();
  // 页签刷新 通知子应用
  const query = getQuery();
  bus.$emit(appName.value, {
    action: 'tab-refresh',
    data: routerParams.value,
    query: query || {}
  });
  bus.$off(`${appName.value}req`, () => {});
});

/** 初始化数据 */
function init() {
  if (props.microParams && props.microParams.microAppName) {
    microData.value = props.microParams;
  } else {
    microData.value = route.meta;
  }
  // microData = microData;
  appName.value = microData.value.microAppCode;
  permissions.value = proxy.$lodash.cloneDeep(getMicroAppPermissions(microData.value.microAppCode)); // 深拷贝
  url.value = microData.value.microAppUrl;
  if (microData.value.microAppSubComponent || microData.value.microAppSubUrl) {
    // 组装子应用的路由信息
    routerParams.value = {
      id: microData.value.id,
      path: microData.value.microAppSubUrl,
      name: route.path, // 是为了缓存
      component: microData.value.microAppSubComponent,
      meta: { ...microData.value, parentPath: route.path, componentName: route.path }
    };
    // 监听子应用的消息，目前只有logout
    bus.$on(`${appName.value}req`, (param) => {
      handleData(param);
    });
    handleRouteChange();
  }
}
/** 主应用传递给子应用的信息权限信息
 * @param {string} key 子应用编码code
 * @returns {object} 返回主应用token,用户信息，菜单和按钮权限信息
 */
function getMicroAppPermissions(key) {
  const token = getToken() || '';
  const userInfo = userStore.userInfo || {};
  // const store = userStore.menuList;
  return { token, userInfo, permissions: microStore.microPermissions[key] };
}
/** tab页签切换，重新设置页面 */
function reInit() {
  keepAlive.value = true;
  url.value = microData.value.microAppUrl;
  handleRouteChange();
}
/** wujie生命周期，预启动时未完成时浏览子应用会调用(比如刷新子页面时，还未来的及启动子应用就调用了页面) */
function afterMount() {
  handleRouteChange();
}
/** 通知子应用跳转路由 **/
function handleRouteChange() {
  if (routerParams.value.path || routerParams.value.component) {
    const query = getQuery();
    bus.$emit(appName.value, {
      action: 'router-change',
      data: routerParams.value,
      query: query || {}
    });
  }

  let apps = microStore.appStorage[appName.value];
  apps = !apps ? [] : apps;

  const item = apps.find((data) => data.name === routerParams.value.name);
  if (!item) {
    apps.push(routerParams.value);
    microStore.appStorage[appName.value] = apps;
  }
}
/** 通知子应用移除路由 **/
function handleRouteRemove() {
  bus.$emit(appName.value, {
    action: 'router-remove',
    data: routerParams.value
  });
  // 如果子应用不是预加载和预执行的APP，页签未有相同name的子应用，清除子应用缓存
  if (!routerParams.value.meta.preloadFlag || routerParams.value.meta.preloadFlag === '0') {
    let index = -1;
    const apps = microStore.appStorage[appName.value];
    // eslint-disable-next-line no-unused-vars
    apps.find((data, i) => {
      if (data.name === routerParams.value.name) {
        index = i;
      }
      return index !== -1;
    });
    if (index !== -1) {
      apps.splice(index, 1);
      microStore.appStorage[appName.value] = apps;
      if (apps.length === 0) {
        delete microStore.appStorage[appName.value];
        // sessionStorage.remove(appName.value);
        // WujieVue.destroyApp(appName.value);

        // WujieVue.setupApp({
        //   name: appName.value,
        //   url: url.value,
        //   props: { appName: appName.value, permissions: permissions },
        //   exec: true,
        //   fiber: true,
        //   plugins: plugins.value
        // });
      }
    }
  }
}
/**
 * 监听到子应用信息并处理
 *  @param  {action,router,params} param 子应用传过来得参数
 */
function handleData(param) {
  if (param.action) {
    switch (param.action) {
      case 'logout':
        proxy.$warning({
          title: '提示',
          content: '登录已过期，即将重新登录！',
          okText: '确定',
          closable: false,
          onOk() {
            // return that.$sdk.logout(false);
          }
        });
        break;
      case 'execFunc':
        {
          // 执行主应用实例上的方法
          if (routerParams.value.meta.parentPath === param.router.path) {
            param.Func.apply(this, param.params);
          }
        }
        break;
      default:
    }
  }
}
/**
 * 页签刷新从url中获取子应用的参数
 * @param  {router,query} param 子应用传过来得参数
 */
function getQuery() {
  const params = getUrlQuery(window.location.search);
  if (params[appName.value]) {
    delete params[appName.value];
    return params;
  }
  return params;
}
function getUrlQuery(url) {
  // const url = window.decodeURIComponent(window.location.search);
  const search = url.replace('?', '');
  // const search = url.replace('?'+appName.value+'='+route.path, "").replace("?",'');
  if (search.length > 0) {
    const pairs = search.split('&');
    const paramsMap = pairs
      .map((pair) => {
        const [key, value] = pair.split('=');
        return [decodeURIComponent(key), decodeURIComponent(value)];
      })
      .reduce((res, [key, value]) => Object.assign(res, { [key]: value }), {});
    return paramsMap;
  }
  return {};
}

function jump(param) {
  if (routerParams.value.meta.parentPath === param.router.path) {
    router.push({
      path: param.router.path,
      query: { ...param.query }
    });
    // 暂存路由信息，防止tab 切换丢失
    routerParams.value = {
      ...routerParams.value,
      path: param.router.meta.microAppSubUrl,
      query: param.query
    };
    bus.$emit(appName.value, {
      action: 'router-push',
      path: param.router.meta.microAppSubUrl,
      query: param.query
    });
  }
}
/**
 * 子应用通过调用此方法向主应用添加新路由并打开新的页签和子应用的页面
 * @param  {router,query} param 子应用传过来得参数
 */
function addRouteAndJump(param) {
  openNewPlatformTabCommon(router, param, {
    microAppName: microData.value.microAppName,
    microAppCode: microData.value.microAppCode,
    microAppUrl: microData.value.microAppUrl
  });
}
</script>
